package me.zhengjie.modules.weixin.analyzer.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import me.chanjar.weixin.common.error.WxErrorException;
import me.chanjar.weixin.mp.api.WxMpService;
import me.chanjar.weixin.mp.bean.result.WxMpUser;
import me.zhengjie.config.constant.WeChatConstant;
import me.zhengjie.constant.ConstantUtils;
import me.zhengjie.modules.system.domain.DisLockUser;
import me.zhengjie.modules.system.domain.WxUser;
import me.zhengjie.modules.system.domain.WxUserRecommand;
import me.zhengjie.modules.system.service.DictDetailService;
import me.zhengjie.modules.system.service.WxUserRecommandService;
import me.zhengjie.modules.system.service.WxUserService;
import me.zhengjie.modules.web.service.mybatisplus.IDisLockUserPlusService;
import me.zhengjie.modules.weixin.analyzer.AbstractAnalyzer;
import me.zhengjie.modules.weixin.dto.WeChatAccount;
import me.zhengjie.modules.weixin.dto.WeChatMessage;
import me.zhengjie.modules.weixin.dto.WeChatMessageRequest;
import me.zhengjie.modules.weixin.enums.WeChatEventEnum;
import me.zhengjie.modules.weixin.message.AnalyzerReplyMessage;
import me.zhengjie.utils.DateUtil;
import me.zhengjie.utils.SpringContextHolder;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.util.CollectionUtils;

import java.sql.Timestamp;
import java.time.LocalDateTime;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 事件分析器
 *
 */
public class EventAnalyzer extends AbstractAnalyzer {
    private static final Logger log = LoggerFactory.getLogger(EventAnalyzer.class);
    public EventAnalyzer() {

    }

    public EventAnalyzer(WeChatAccount account, Map<String, Object> message) {
        this.account = account;
        this.message = message;
    }

    @Override
    public WeChatMessage analyze() {

        String event = (String) message.get("Event");
        WeChatEventEnum eventEnum = WeChatEventEnum.get(event);

        WeChatMessage weChatMessage = account.getMessages().parallelStream()
                .filter(m -> Arrays.asList(m.getMsgType().split("\\|")).contains(event)).findFirst().orElse(new WeChatMessage());

        weChatMessage.setMsgType(event);
        String openId = (String) message.get("FromUserName");
        final String eventKey = StringUtils.defaultString((String) message.get("EventKey"));
        String qrScene = eventKey.replace("qrscene_", "");
        List<AnalyzerReplyMessage> replyMessages = null;
        WeChatMessageRequest mqRequest = new WeChatMessageRequest();
        mqRequest.setAppId(account.getAppId());
        mqRequest.setMsgType(weChatMessage.getMsgType());
        mqRequest.setReceiveMsg(message);
        mqRequest.setMsgId(UUID.randomUUID().toString());
        mqRequest.setOpenId(openId);
        WxUserService wxUserService = SpringContextHolder.getBean(WxUserService.class);
        IDisLockUserPlusService dictDetailService = SpringContextHolder.getBean(IDisLockUserPlusService.class);
        LambdaQueryWrapper<DisLockUser> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(DisLockUser::getLockStatus,ConstantUtils.Valid);
        List<DisLockUser> lockUserTime = dictDetailService.list(wrapper);
        String lockTime = "";
        if (CollectionUtils.isEmpty(lockUserTime)){
            lockTime = String.valueOf(ConstantUtils.LockUserDefaultMonth);
        }else {
            lockTime = String.valueOf(lockUserTime.get(0).getLockMonth());
        }
        WxMpService wxMpService = SpringContextHolder.getBean(WxMpService.class);
        WxUserRecommandService recommandService = SpringContextHolder.getBean(WxUserRecommandService.class);
        WxUser wxUser = wxUserService.findByOpenId(openId);
        // 有特殊逻辑，可以针对不同事件分别处理，方便后续改为消息走数据库配置
        switch (eventEnum) {
            case subscribe:
                log.info("关注事件:"+openId+",qrScene="+qrScene);
                String superior = "";
                if (StringUtils.isNotBlank(qrScene) && qrScene.startsWith("ATMR_")) {
                    //当作推荐过来的 qrscene结果 openId
                    qrScene = qrScene.replace(WeChatConstant.QrCodeScenePrefix,"");
                    superior = qrScene;
                    WxUserRecommand one = recommandService.findOne(qrScene, openId);
                    if (null == one){
                        log.info("推荐表中不存在数据插入");
                        WxMpUser wxMpUser = null;
                        try {
                            wxMpUser = wxMpService.getUserService().userInfo(openId);
                        } catch (WxErrorException e) {
                        }
                        WxUserRecommand wxUserRecommand = new WxUserRecommand();
                        wxUserRecommand.setOpenId(qrScene);
                        wxUserRecommand.setObjOpenid(openId);
                        wxUserRecommand.setCreateTime(Timestamp.valueOf(LocalDateTime.now()));
                        wxUserRecommand.setNickName("");
                        wxUserRecommand.setHeadPic("");
                        if (null != wxMpUser){
                            wxUserRecommand.setNickName(wxMpUser.getNickname());
                            wxUserRecommand.setHeadPic(wxMpUser.getHeadImgUrl());
                        }
                        try {
                            recommandService.create(wxUserRecommand);
                            log.info("推荐表中插入成功");
                        } catch (Exception e) {
                            log.info("推荐表中插入数据失败");
                        }
                    }
                }
                if (null != wxUser){
                    log.info("更新关注时间"+openId);
                    wxUser.setSubscribeTime(DateUtil.date2String(new Date()));
                    wxUser.setSubscribe(Boolean.TRUE.toString());
                    wxUser.setUpdateTime(DateUtil.TimestampNow());
                    wxUserService.update(wxUser);
                }else {
                    log.info("关注插入用户表"+openId);
                    WxUser user = new WxUser();
                    try {
                        WxMpUser wxMpUser = wxMpService.getUserService().userInfo(openId);
                        user.setNickname(wxMpUser.getNickname());
                        user.setHeadimgurl(wxMpUser.getHeadImgUrl());
                    } catch (WxErrorException e) {
                        e.printStackTrace();
                    }
                    user.setSubscribe(Boolean.TRUE.toString());
                    user.setSubscribeTime(DateUtil.date2String(new Date()));
                    user.setOpenId(openId);
                    Date date = DateUtil.addMonth(new Date(), Integer.parseInt(lockTime));
                    user.setLockTime(DateUtil.dateConvertTimestamp(date));
                    if (StringUtils.isNotBlank(superior)){
                        WxUser superiorUser = wxUserService.findByOpenId(superior);
                        if (Objects.nonNull(superiorUser)){
                            user.setSuperiorMobile(superiorUser.getMobile());
                            user.setSuperiorNickName(superiorUser.getNickname());
                            user.setSuperiorRealName(superiorUser.getRealName());
                        }
                    }
                    wxUserService.create(user);
                }
                break;
            case unsubscribe:
                log.info("取消关注事件");
                if (null != wxUser){
                    wxUser.setSubscribe(Boolean.FALSE.toString());
                    wxUser.setUpdateTime(DateUtil.TimestampNow());
                    wxUserService.update(wxUser);
                }
                break;
            case VIEW:
                break;
            case view_miniprogram:
                break;
            case CLICK:
                if (StringUtils.isNotBlank(eventKey)) {
                    replyMessages = weChatMessage.getReplyMessage().parallelStream()
                            .filter(r -> r.getRule().equalsIgnoreCase(eventKey))
                            .sorted(Comparator.comparing(AnalyzerReplyMessage::getPriority))
                            .limit(1).collect(Collectors.toList());
                    // 定位到精确的一条回复即可
                    weChatMessage.setReplyMessage(replyMessages);
                }
                break;
            case LOCATION:
                break;
            case SCAN:
                if (StringUtils.isNotBlank(qrScene)) {

                }
                break;
            case user_get_card:
                break;
            case pic_photo_or_album:
            case pic_weixin:
            case pic_sysphoto:
                break;
            default:
                break;
        }

        return weChatMessage;
    }
}
